home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_1 / assignwedge / assignwedge.c < prev    next >
C/C++ Source or Header  |  1992-07-03  |  22KB  |  952 lines

  1. /*
  2. **    AssignWedge - AmigaDOS 2.04 utility
  3. **
  4. **    Copyright © 1992 by Olaf `Olsen' Barthel
  5. **        All Rights Reserved
  6. */
  7.  
  8. #include <intuition/intuitionbase.h>
  9. #include <workbench/startup.h>
  10. #include <libraries/locale.h>
  11. #include <dos/dosextens.h>
  12. #include <exec/execbase.h>
  13. #include <libraries/asl.h>
  14. #include <dos/dostags.h>
  15. #include <exec/memory.h>
  16.  
  17. #include <clib/intuition_protos.h>
  18. #include <clib/utility_protos.h>
  19. #include <clib/locale_protos.h>
  20. #include <clib/exec_protos.h>
  21. #include <clib/dos_protos.h>
  22. #include <clib/asl_protos.h>
  23.  
  24.     /* Create the requester strings. */
  25.  
  26. #define STRINGARRAY
  27.  
  28. #include "assignwedge.h"
  29.  
  30.     /* The requester selection IDs. */
  31.  
  32. enum    {    REQ_CANCEL, REQ_RETRY, REQ_ASSIGN, REQ_MOUNT, REQ_DENY };
  33.  
  34.     /* Some handy signal macros. */
  35.  
  36. #define SIG_KILL    SIGBREAKF_CTRL_C
  37. #define SIG_NOTIFY    (1 << MainPort -> mp_SigBit)
  38.  
  39.     /* The MC680x0 `jump to absolute address' opcode. */
  40.  
  41. #define JMP_ABS 0x4EF9
  42.  
  43.     /* A simple wedge definition which is to consist of a jmp
  44.      * instruction and the destination of the jump.
  45.      */
  46.  
  47. struct Wedge
  48. {
  49.     UWORD         Command;
  50.     APTR         Address;
  51. };
  52.  
  53.     /* Process and command names which are no longer allowed to
  54.      * access certain paths will be identified by information
  55.      * to be found in a list. The following structure definition
  56.      * holds the necessary data (name and process base address).
  57.      */
  58.  
  59. struct DenyNode
  60. {
  61.     struct MinNode     Node;
  62.  
  63.     struct Process    *Process;
  64.     UBYTE         Name[40],
  65.              ProgramName[40];
  66. };
  67.  
  68.     /* The library vector offset of the intuition.library routine to patch. */
  69.  
  70. extern ULONG __far     LVOEasyRequestArgs;
  71.  
  72.     /* The version ID tag. */
  73.  
  74. STATIC UBYTE Version[]    = "\0$VER: AssignWedge 1.1 (12.4.92)";
  75.  
  76.     /* Global and shared library identifiers. */
  77.  
  78. struct IntuitionBase    *IntuitionBase;
  79. struct ExecBase        *SysBase;
  80. struct DosLibrary    *DOSBase;
  81. struct Library        *UtilityBase;
  82. struct Library        *AslBase;
  83.  
  84.     /* Locale support. */
  85.  
  86. struct LocaleBase    *LocaleBase;
  87. struct Catalog        *Catalog;
  88.  
  89.     /* Registration of programs which are not allowed to
  90.      * access certain devices.
  91.      */
  92.  
  93. struct SignalSemaphore     DenySemaphore;
  94. struct MinList         DenyList;
  95.  
  96.     /* The following counter and the associated access semaphore help
  97.      * to keep track of the number of programs currently using the
  98.      * patched EasyRequestArgs() routine.
  99.      */
  100.  
  101. struct SignalSemaphore     RunSemaphore;
  102. LONG             RunCount;
  103.  
  104.     /* Handshake data. */
  105.  
  106. struct Process        *MainProcess;
  107. struct MsgPort        *MainPort;
  108. BYTE             Removed;
  109.  
  110.     /* To compensate for possible incompatibilities introduced by internationalized
  111.      * requester texts, we will try to determine the text to turn up when an
  112.      * `please insert volume' requester is opened. The `SearchName' will receive
  113.      * the string to look for.
  114.      */
  115.  
  116. UBYTE             SearchName[256];
  117.  
  118.     /* Function prototypes. */
  119.  
  120. LONG __saveds         Main(VOID);
  121. STRPTR __regargs     GetString(LONG ID);
  122. LONG __saveds __asm     NewEasyRequestArgs(register __a0 struct Window *Window,register __a1 struct EasyStruct *EasyStruct,register __a2 ULONG *IDCMPPtr,register __a3 APTR *Args);
  123. LONG            (* __asm OldEasyRequestArgs)(register __a0 struct Window *,register __a1 struct EasyStruct *,register __a2 ULONG *,register __a3 APTR *,register __a6 struct IntuitionBase *);
  124.  
  125. LONG __saveds
  126. Main()
  127. {
  128.     struct WBStartup    *WBenchMsg    = NULL;
  129.     LONG             ReturnCode    = RETURN_FAIL;
  130.  
  131.         /* Set up ExecBase */
  132.  
  133.     SysBase = *(struct ExecBase **)4;
  134.  
  135.         /* Determine current process identifier. */
  136.  
  137.     MainProcess = (struct Process *)SysBase -> ThisTask;
  138.  
  139.         /* Are we running from CLI? If so, wait for Workbench
  140.          * startup message. 
  141.          */
  142.  
  143.     if(!MainProcess -> pr_CLI)
  144.     {
  145.         WaitPort(&MainProcess -> pr_MsgPort);
  146.  
  147.         WBenchMsg = (struct WBStartup *)GetMsg(&MainProcess -> pr_MsgPort);
  148.     }
  149.  
  150.         /* Try to find the global handshake port and if present
  151.          * send a termination signal.
  152.          */
  153.  
  154.     if(MainPort = FindPort("AssignWedge Rendezvous"))
  155.     {
  156.         Signal(MainPort -> mp_SigTask,SIG_KILL);
  157.  
  158.         ReturnCode = RETURN_OK;
  159.     }
  160.     else
  161.     {
  162.             /* Are we running under Kickstart version 37 or higher? */
  163.  
  164.         if(SysBase -> LibNode . lib_Version > 36)
  165.         {
  166.                 /* Create the global handshake port. */
  167.  
  168.             if(MainPort = CreateMsgPort())
  169.             {
  170.                     /* Give it a name and add it to the public list. */
  171.  
  172.                 MainPort -> mp_Node . ln_Name = "AssignWedge Rendezvous";
  173.  
  174.                 AddPort(MainPort);
  175.  
  176.                     /* Open the required libraries. */
  177.  
  178.                 if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  179.                 {
  180.                     if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  181.                     {
  182.                         if(UtilityBase = OpenLibrary("utility.library",37))
  183.                         {
  184.                             if(AslBase = OpenLibrary(AslName,37))
  185.                             {
  186.                                 struct Wedge *Wedge;
  187.  
  188.                                     /* Try to open locale.library, but don't panic
  189.                                      * if it's not available.
  190.                                      */
  191.  
  192.                                 if(LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library",38))
  193.                                 {
  194.                                     if(!(Catalog = OpenCatalog(NULL,"assignwedge.catalog",
  195.                                         OC_BuiltInLanguage,    "english",
  196.                                         OC_BuiltInCodeSet,    0,
  197.                                     TAG_DONE)))
  198.                                     {
  199.                                         CloseLibrary(LocaleBase);
  200.  
  201.                                         LocaleBase = NULL;
  202.                                     }
  203.                                 }
  204.  
  205.                                     /* Initialize the access semaphore. */
  206.  
  207.                                 InitSemaphore(&RunSemaphore);
  208.  
  209.                                 RunCount = 0;
  210.  
  211.                                     /* Initialize the access semaphore and
  212.                                      * the list of programs to which access
  213.                                      * to certain devices has been denied.
  214.                                      */
  215.  
  216.                                 InitSemaphore(&DenySemaphore);
  217.  
  218.                                 NewList((struct List *)&DenyList);
  219.  
  220.                                     /* Allocate a system library function wedge. */
  221.  
  222.                                 if(Wedge = AllocMem(sizeof(struct Wedge),MEMF_PUBLIC))
  223.                                 {
  224.                                     struct DenyNode    *NextNode,
  225.                                             *DenyNode;
  226.  
  227.                                         /* Initialize the wedge. */
  228.  
  229.                                     Wedge -> Command = JMP_ABS;
  230.                                     Wedge -> Address = (APTR)NewEasyRequestArgs;
  231.  
  232.                                     Removed = FALSE;
  233.  
  234.                                         /* Install the wedge. */
  235.  
  236.                                     Forbid();
  237.  
  238.                                     OldEasyRequestArgs = (APTR)SetFunction(IntuitionBase,(LONG)&LVOEasyRequestArgs,(APTR)Wedge);
  239.  
  240.                                         /* Make sure the data gets written to memory. */
  241.  
  242.                                     CacheClearU();
  243.  
  244.                                         /* Put up an example requester. Note: this requester
  245.                                          * will be trapped by the wedge routine, giving us
  246.                                          * the string to look for in the future.
  247.                                          */
  248.  
  249.                                     ErrorReport(ERROR_DEVICE_NOT_MOUNTED,REPORT_INSERT,(ULONG)"Test:",NULL);
  250.  
  251.                                         /* We're up and running now. Note that the
  252.                                          * Forbid() will be broken by the Wait() for
  253.                                          * a ^C signal.
  254.                                          */
  255.  
  256.                                     Wait(SIG_KILL);
  257.  
  258.                                         /* We are no longer running,
  259.                                          * tell the wedge routine to
  260.                                          * skip the `access denied'
  261.                                          * part which requires the
  262.                                          * list to be initialized.
  263.                                          */
  264.  
  265.                                     Removed = TRUE;
  266.  
  267.                                         /* Redirect the wedge pointer to
  268.                                          * the original routine.
  269.                                          */
  270.  
  271.                                     Wedge -> Address = OldEasyRequestArgs;
  272.  
  273.                                         /* Make sure that the data
  274.                                          * gets written to memory.
  275.                                          */
  276.  
  277.                                     CacheClearU();
  278.  
  279.                                         /* Turn the multitasking back on. */
  280.  
  281.                                     Permit();
  282.  
  283.                                         /* Clear pending signals. */
  284.  
  285.                                     SetSignal(0,SIG_NOTIFY);
  286.  
  287.                                         /* Wait until our wedge routine
  288.                                          * is no longer in use.
  289.                                          */
  290.  
  291.                                     while(RunCount)
  292.                                         Wait(SIG_NOTIFY);
  293.  
  294.                                         /* Clear the `access denied' list. */
  295.  
  296.                                     DenyNode = (struct DenyNode *)DenyList . mlh_Head;
  297.  
  298.                                     while(NextNode = (struct DenyNode *)DenyNode -> Node . mln_Succ)
  299.                                     {
  300.                                         FreeVec(DenyNode);
  301.  
  302.                                         DenyNode = NextNode;
  303.                                     }
  304.  
  305.                                         /* Successful termination. */
  306.  
  307.                                     ReturnCode = RETURN_OK;
  308.                                 }
  309.  
  310.                                     /* Close the resources
  311.                                      * we had allocated,
  312.                                      * but *not* the wedge
  313.                                      * memory.
  314.                                      */
  315.  
  316.                                 if(Catalog)
  317.                                     CloseCatalog(Catalog);
  318.  
  319.                                 if(LocaleBase)
  320.                                     CloseLibrary(LocaleBase);
  321.  
  322.                                 CloseLibrary(AslBase);
  323.                             }
  324.  
  325.                             CloseLibrary(UtilityBase);
  326.                         }
  327.  
  328.                         CloseLibrary(IntuitionBase);
  329.                     }
  330.  
  331.                     CloseLibrary(DOSBase);
  332.                 }
  333.  
  334.                     /* Remove the global handshake port. */
  335.  
  336.                 RemPort(MainPort);
  337.  
  338.                 DeleteMsgPort(MainPort);
  339.             }
  340.         }
  341.     }
  342.  
  343.         /* If run from Workbench, reply the startup message. */
  344.  
  345.     if(WBenchMsg)
  346.     {
  347.         Forbid();
  348.  
  349.         ReplyMsg(&WBenchMsg -> sm_Message);
  350.     }
  351.  
  352.         /* That's all folks. */
  353.  
  354.     return(ReturnCode);
  355. }
  356.  
  357.     /* GetString(LONG ID):
  358.      *
  359.      *    Fetch a text from the database.
  360.      */
  361.  
  362. STRPTR __regargs
  363. GetString(LONG ID)
  364. {
  365.     STRPTR    Builtin = NULL;
  366.     WORD    i;
  367.  
  368.         /* Try to find the builtin string to match the ID we received. */
  369.  
  370.     if(AppStrings[ID] . as_ID != ID)
  371.     {
  372.         for(i = 0 ; i < (sizeof(AppStrings) / sizeof(struct AppString)) ; i++)
  373.         {
  374.             if(AppStrings[i] . as_ID == ID)
  375.             {
  376.                 Builtin = AppStrings[i] . as_Str;
  377.  
  378.                 break;
  379.             }
  380.         }
  381.     }
  382.     else
  383.         Builtin = AppStrings[ID] . as_Str;
  384.  
  385.         /* If locale.library is installed and the database catalog was
  386.          * successfully opened, query the library's idea of the corresponding
  387.          * text string. Otherwise, return the builtin string.
  388.          */
  389.  
  390.     if(LocaleBase)
  391.         return(GetCatalogStr(Catalog,ID,Builtin));
  392.     else
  393.         return(Builtin);
  394. }
  395.  
  396.     /* NewEasyRequestArgs():
  397.      *
  398.      *    A custom version of the original EasyRequest() routine which
  399.      *    is to provide enhanced options whenever a DOS handler puts
  400.      *    up a `REPORT_INSERT' style requester.
  401.      */
  402.  
  403. LONG __saveds __asm
  404. NewEasyRequestArgs(register __a0 struct Window *Window,register __a1 struct EasyStruct *EasyStruct,register __a2 ULONG *IDCMPPtr,register __a3 APTR *Args)
  405. {
  406.     struct Process    *ThisProcess = (struct Process *)SysBase -> ThisTask;
  407.     LONG         Result;
  408.  
  409.         /* This may be the first call to the new routine, made by the
  410.          * main program trying to determine the text to look for in
  411.          * future requesters.
  412.          */
  413.  
  414.     if(!SearchName[0] && ThisProcess == MainProcess)
  415.     {
  416.         strcpy(SearchName,Args[0]);
  417.  
  418.         return(REQ_CANCEL);
  419.     }
  420.  
  421.         /* Increment the use count. */
  422.  
  423.     ObtainSemaphore(&RunSemaphore);
  424.  
  425.     RunCount++;
  426.  
  427.     ReleaseSemaphore(&RunSemaphore);
  428.  
  429.         /* Is the caller a process, i.e. will it be able to use all
  430.          * DOS routines?
  431.          */
  432.  
  433.     if(ThisProcess -> pr_Task . tc_Node . ln_Type == NT_PROCESS)
  434.     {
  435.             /* Do the arguments match the pattern we had expected and
  436.              * are DOS requesters enabled?
  437.              */
  438.  
  439.         if(!Strnicmp(EasyStruct -> es_TextFormat,"%s",2) && Args && ThisProcess -> pr_WindowPtr != (APTR)-1)
  440.         {
  441.                 /* Did we get any calling parameters? */
  442.  
  443.             if(Args[0])
  444.             {
  445.                     /* Does the first argument match the `please insert volume...' title? */
  446.  
  447.                 if(!Stricmp(Args[0],SearchName))
  448.                 {
  449.                     UBYTE *DirBuffer;
  450.  
  451.                         /* Allocate a temporary storage buffer
  452.                          * required by a number of routines
  453.                          * lateron.
  454.                          */
  455.  
  456.                     if(DirBuffer = (UBYTE *)AllocVec(512 + 60,MEMF_ANY))
  457.                     {
  458.                         UBYTE                *HailBuffer;
  459.                         struct EasyStruct __aligned     Easy = *EasyStruct;
  460.                         struct DenyNode            *DenyNode;
  461.                         struct FileRequester        *AslFileRequest;
  462.                         struct Screen            *FirstScreen;
  463.                         ULONG                 IntuiLock;
  464.                         BPTR                 In,Out;
  465.  
  466.                             /* Gain access to the list of
  467.                              * programs to which access to
  468.                              * some devices has been denied.
  469.                              */
  470.  
  471.                         ObtainSemaphore(&DenySemaphore);
  472.  
  473.                         DenyNode = (struct DenyNode *)DenyList . mlh_Head;
  474.  
  475.                             /* If this process has a CLI structure
  476.                              * attached, look for a command name
  477.                              * to match a list entry.
  478.                              */
  479.  
  480.                         if(ThisProcess -> pr_CLI)
  481.                         {
  482.                                 /* Process the list... */
  483.  
  484.                             while(DenyNode -> Node . mln_Succ)
  485.                             {
  486.                                     /* Does this entry refer to
  487.                                      * a command name?
  488.                                      */
  489.  
  490.                                 if(DenyNode -> ProgramName[0])
  491.                                 {
  492.                                         /* Does the name of the device
  493.                                          * in question match the name
  494.                                          * in the list entry?
  495.                                          */
  496.  
  497.                                     if(!Stricmp(DenyNode -> Name,Args[1]))
  498.                                     {
  499.                                             /* Obtain the name of the program
  500.                                              * currently running.
  501.                                              */
  502.  
  503.                                         if(GetProgramName(DirBuffer,512))
  504.                                         {
  505.                                                 /* Does the name match the one
  506.                                                  * in the list entry?
  507.                                                  */
  508.  
  509.                                             if(!Stricmp(FilePart(DirBuffer),DenyNode -> ProgramName))
  510.                                             {
  511.                                                     /* Release the access semaphore. */
  512.  
  513.                                                 ReleaseSemaphore(&DenySemaphore);
  514.  
  515.                                                     /* Free the temporary storage buffer. */
  516.  
  517.                                                 FreeVec(DirBuffer);
  518.  
  519.                                                     /* Decrement use count. */
  520.  
  521.                                                 ObtainSemaphore(&RunSemaphore);
  522.  
  523.                                                 RunCount--;
  524.  
  525.                                                 ReleaseSemaphore(&RunSemaphore);
  526.  
  527.                                                     /* Tell the main process to take a
  528.                                                      * look at the use count.
  529.                                                      */
  530.  
  531.                                                 Signal(MainProcess,SIG_NOTIFY);
  532.  
  533.                                                     /* Return failure. */
  534.  
  535.                                                 return(REQ_CANCEL);
  536.                                             }
  537.                                         }
  538.                                     }
  539.                                 }
  540.  
  541.                                     /* Proceed to the next list entry. */
  542.  
  543.                                 DenyNode = (struct DenyNode *)DenyNode -> Node . mln_Succ;
  544.                             }
  545.                         }
  546.                         else
  547.                         {
  548.                                 /* Run down the list. */
  549.  
  550.                             while(DenyNode -> Node . mln_Succ)
  551.                             {
  552.                                     /* Does the process identifier match the
  553.                                      * one in the list entry?
  554.                                      */
  555.  
  556.                                 if(DenyNode -> Process == ThisProcess)
  557.                                 {
  558.                                         /* Does the name of the device in
  559.                                          * question match the one in the
  560.                                          * list entry?
  561.                                          */
  562.  
  563.                                     if(!Stricmp(DenyNode -> Name,Args[1]))
  564.                                     {
  565.                                             /* Release the access semaphore. */
  566.  
  567.                                         ReleaseSemaphore(&DenySemaphore);
  568.  
  569.                                             /* Free the temporary storage buffer. */
  570.  
  571.                                         FreeVec(DirBuffer);
  572.  
  573.                                             /* Decrement use count. */
  574.  
  575.                                         ObtainSemaphore(&RunSemaphore);
  576.  
  577.                                         RunCount--;
  578.  
  579.                                         ReleaseSemaphore(&RunSemaphore);
  580.  
  581.                                             /* Tell the main process to take a
  582.                                              * look at the use count.
  583.                                              */
  584.  
  585.                                         Signal(MainProcess,SIG_NOTIFY);
  586.  
  587.                                             /* Return failure. */
  588.  
  589.                                         return(REQ_CANCEL);
  590.                                     }
  591.                                 }
  592.  
  593.                                     /* Proceed to the next entry. */
  594.  
  595.                                 DenyNode = (struct DenyNode *)DenyNode -> Node . mln_Succ;
  596.                             }
  597.                         }
  598.  
  599.                             /* Release the access semaphore. */
  600.  
  601.                         ReleaseSemaphore(&DenySemaphore);
  602.  
  603.                             /* Split the buffer to create the directory
  604.                              * requester title string.
  605.                              */
  606.  
  607.                         HailBuffer = DirBuffer + 512;
  608.  
  609.                             /* Fill in the `Retry|Assign|Mount|Deny|Cancel' buttons. */
  610.  
  611.                         Easy . es_GadgetFormat = GetString(MSG_PROMPT_GAD);
  612.  
  613.                             /* Put up the requester and decide what to do. */
  614.  
  615.                         switch(Result = OldEasyRequestArgs(Window,&Easy,IDCMPPtr,Args,IntuitionBase))
  616.                         {
  617.                             case REQ_ASSIGN:
  618.  
  619.                                     /* Try to obtain the name of the current directory,
  620.                                      * most programs to look for assignments or volume
  621.                                      * names will be happy if assignments are made
  622.                                      * referring to their home directories.
  623.                                      */
  624.  
  625.                                 if(!GetCurrentDirName(DirBuffer,512))
  626.                                     DirBuffer[0] = 0;
  627.  
  628.                                     /* Set up the window title. */
  629.  
  630.                                 sprintf(HailBuffer,GetString(MSG_HAIL_GAD),Args[1]);
  631.  
  632.                                     /* create the directory requester. */
  633.  
  634.                                 if(AslFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
  635.                                     ASL_Dir,    DirBuffer,
  636.                                     ASL_Hail,    HailBuffer,
  637.                                     ASL_OKText,    GetString(MSG_ASSIGN_GAD),
  638.                                     ASL_Window,    Window,
  639.                                     ASL_FuncFlags,    FILF_NEWIDCMP,
  640.                                     ASL_ExtFlags1,    FIL1F_NOFILES,
  641.                                 TAG_DONE))
  642.                                 {
  643.                                         /* Remember the first screen ID. */
  644.  
  645.                                     IntuiLock = LockIBase(NULL);
  646.  
  647.                                     FirstScreen = IntuitionBase -> FirstScreen;
  648.  
  649.                                     UnlockIBase(IntuiLock);
  650.  
  651.                                         /* Move the screen the requester is to appear on
  652.                                          * up if necessary.
  653.                                          */
  654.  
  655.                                     if(Window -> WScreen -> TopEdge > 0)
  656.                                         MoveScreen(Window -> WScreen,0,-Window -> WScreen -> TopEdge);
  657.  
  658.                                         /* Move the screen to the front. */
  659.  
  660.                                     ScreenToFront(Window -> WScreen);
  661.  
  662.                                         /* Display the requester. */
  663.  
  664.                                     while(AslRequestTags(AslFileRequest,TAG_DONE))
  665.                                     {
  666.                                         APTR OldWindowPtr = ThisProcess -> pr_WindowPtr;
  667.                                         BPTR FileLock;
  668.  
  669.                                             /* Disable the system requesters. */
  670.  
  671.                                         ThisProcess -> pr_WindowPtr = (APTR)-1;
  672.  
  673.                                             /* Try to access the directory the
  674.                                              * user has just selected.
  675.                                              */
  676.  
  677.                                         if(FileLock = Lock(AslFileRequest -> rf_Dir,ACCESS_READ))
  678.                                         {
  679.                                                 /* Try to create the assignment. */
  680.  
  681.                                             if(!AssignLock(Args[1],FileLock))
  682.                                             {
  683.                                                     /* Oops, something went wrong. */
  684.  
  685.                                                 DisplayBeep(Window -> WScreen);
  686.  
  687.                                                 UnLock(FileLock);
  688.                                             }
  689.                                             else
  690.                                             {
  691.                                                     /* Restore the window pointer. */
  692.  
  693.                                                 ThisProcess -> pr_WindowPtr = OldWindowPtr;
  694.  
  695.                                                 break;
  696.                                             }
  697.                                         }
  698.                                         else
  699.                                             DisplayBeep(Window -> WScreen);
  700.  
  701.                                             /* Restore the window pointer. */
  702.  
  703.                                         ThisProcess -> pr_WindowPtr = OldWindowPtr;
  704.                                     }
  705.  
  706.                                         /* Free the requester data. */
  707.  
  708.                                     FreeAslRequest(AslFileRequest);
  709.  
  710.                                         /* Pop the screen which was frontmost
  711.                                          * before the requester was displayed
  712.                                          * back to the front.
  713.                                          */
  714.  
  715.                                     IntuiLock = LockIBase(0);
  716.  
  717.                                     if(FirstScreen == IntuitionBase -> FirstScreen)
  718.                                         UnlockIBase(IntuiLock);
  719.                                     else
  720.                                     {
  721.                                         struct Screen    *Screen = IntuitionBase -> FirstScreen;
  722.                                         BYTE         IsValid = FALSE;
  723.  
  724.                                             /* Try to determine if the screen ID we
  725.                                              * remembered is still valid.
  726.                                              */
  727.  
  728.                                         while(Screen && !IsValid)
  729.                                         {
  730.                                             if(Screen == FirstScreen)
  731.                                                 IsValid = TRUE;
  732.                                             else
  733.                                                 Screen = Screen -> NextScreen;
  734.                                         }
  735.  
  736.                                         Forbid();
  737.  
  738.                                         UnlockIBase(IntuiLock);
  739.  
  740.                                             /* Push the screen to the front. */
  741.  
  742.                                         if(IsValid)
  743.                                             ScreenToFront(FirstScreen);
  744.  
  745.                                         Permit();
  746.                                     }
  747.                                 }
  748.  
  749.                                     /* Free the directory buffer. */
  750.  
  751.                                 FreeVec(DirBuffer);
  752.  
  753.                                     /* Decrement use count. */
  754.  
  755.                                 ObtainSemaphore(&RunSemaphore);
  756.  
  757.                                 RunCount--;
  758.  
  759.                                 ReleaseSemaphore(&RunSemaphore);
  760.  
  761.                                     /* Tell the main process to take a
  762.                                      * look at the use count.
  763.                                      */
  764.  
  765.                                 Signal(MainProcess,SIG_NOTIFY);
  766.  
  767.                                     /* Tell AmigaDOS to take a second look at the
  768.                                      * device list.
  769.                                      */
  770.  
  771.                                 return(REQ_RETRY);
  772.  
  773.                             case REQ_MOUNT:
  774.  
  775.                                     /* Open input stream. */
  776.  
  777.                                 if(In = Open("NIL:",MODE_OLDFILE))
  778.                                 {
  779.                                         /* Open output stream. */
  780.  
  781.                                     if(Out = Open("NIL:",MODE_OLDFILE))
  782.                                     {
  783.                                         APTR OldPtr = ThisProcess -> pr_WindowPtr;
  784.  
  785.                                             /* Enter the mount command string. */
  786.  
  787.                                         sprintf(DirBuffer,"Mount >NIL: <NIL: %s:",Args[1]);
  788.  
  789.                                             /* Disable DOS requesters. */
  790.  
  791.                                         ThisProcess -> pr_WindowPtr = (APTR)-1;
  792.  
  793.                                             /* Execute the mount command. */
  794.  
  795.                                         SystemTags(DirBuffer,
  796.                                             SYS_Input,    In,
  797.                                             SYS_Output,    Out,
  798.                                         TAG_DONE);
  799.  
  800.                                             /* Restore window pointer. */
  801.  
  802.                                         ThisProcess -> pr_WindowPtr = OldPtr;
  803.  
  804.                                             /* Close output stream. */
  805.  
  806.                                         Close(Out);
  807.                                     }
  808.  
  809.                                         /* Close input stream. */
  810.  
  811.                                     Close(In);
  812.                                 }
  813.  
  814.                                     /* Free the directory buffer. */
  815.  
  816.                                 FreeVec(DirBuffer);
  817.  
  818.                                     /* Decrement use count. */
  819.  
  820.                                 ObtainSemaphore(&RunSemaphore);
  821.  
  822.                                 RunCount--;
  823.  
  824.                                 ReleaseSemaphore(&RunSemaphore);
  825.  
  826.                                     /* Tell the main process to take a
  827.                                      * look at the use count.
  828.                                      */
  829.  
  830.                                 Signal(MainProcess,SIG_NOTIFY);
  831.  
  832.                                     /* Tell AmigaDOS to take a second look at the
  833.                                      * device list.
  834.                                      */
  835.  
  836.                                 return(REQ_RETRY);
  837.  
  838.                             case REQ_DENY:
  839.  
  840.                                     /* If not about to be removed, allocate an `access denied' node. */
  841.  
  842.                                 if(!Removed)
  843.                                 {
  844.                                     if(DenyNode = (struct DenyNode *)AllocVec(sizeof(struct DenyNode),MEMF_CLEAR))
  845.                                     {
  846.                                             /* Fill in the current process ID. */
  847.  
  848.                                         DenyNode -> Process = ThisProcess;
  849.  
  850.                                             /* Copy the name of the device in question. */
  851.  
  852.                                         strcpy(DenyNode -> Name,Args[1]);
  853.  
  854.                                             /* If this process has a CLI structure attached,
  855.                                              * try to remember the program name.
  856.                                              */
  857.  
  858.                                         if(ThisProcess -> pr_CLI)
  859.                                         {
  860.                                             if(GetProgramName(DirBuffer,512))
  861.                                                 strcpy(DenyNode -> ProgramName,FilePart(DirBuffer));
  862.                                         }
  863.  
  864.                                             /* Gain access to the list. */
  865.  
  866.                                         ObtainSemaphore(&DenySemaphore);
  867.  
  868.                                             /* Add the entry to the list. */
  869.  
  870.                                         AddTail((struct List *)&DenyList,(struct Node *)DenyNode);
  871.  
  872.                                             /* Release the semaphore again. */
  873.  
  874.                                         ReleaseSemaphore(&DenySemaphore);
  875.                                     }
  876.                                 }
  877.  
  878.                                     /* Free the directory buffer. */
  879.  
  880.                                 FreeVec(DirBuffer);
  881.  
  882.                                     /* Decrement use count. */
  883.  
  884.                                 ObtainSemaphore(&RunSemaphore);
  885.  
  886.                                 RunCount--;
  887.  
  888.                                 ReleaseSemaphore(&RunSemaphore);
  889.  
  890.                                     /* Tell the main process to take a
  891.                                      * look at the use count.
  892.                                      */
  893.  
  894.                                 Signal(MainProcess,SIG_NOTIFY);
  895.  
  896.                                     /* Return failure. */
  897.  
  898.                                 return(REQ_CANCEL);
  899.  
  900.                             default:
  901.  
  902.                                     /* Free the directory buffer. */
  903.  
  904.                                 FreeVec(DirBuffer);
  905.  
  906.                                     /* Decrement use count. */
  907.  
  908.                                 ObtainSemaphore(&RunSemaphore);
  909.  
  910.                                 RunCount--;
  911.  
  912.                                 ReleaseSemaphore(&RunSemaphore);
  913.  
  914.                                     /* Tell the main process to take a
  915.                                      * look at the use count.
  916.                                      */
  917.  
  918.                                 Signal(MainProcess,SIG_NOTIFY);
  919.  
  920.                                     /* Return the result (can be either `retry' or `cancel'). */
  921.  
  922.                                 return(Result);
  923.                         }
  924.                     }
  925.                 }
  926.             }
  927.         }
  928.     }
  929.  
  930.         /* In any other case, use the standard call. */
  931.  
  932.     Result = OldEasyRequestArgs(Window,EasyStruct,IDCMPPtr,Args,IntuitionBase);
  933.  
  934.         /* Decrement use count. */
  935.  
  936.     ObtainSemaphore(&RunSemaphore);
  937.  
  938.     RunCount--;
  939.  
  940.     ReleaseSemaphore(&RunSemaphore);
  941.  
  942.         /* Tell the main process to take a
  943.          * look at the use count.
  944.          */
  945.  
  946.     Signal(MainProcess,SIG_NOTIFY);
  947.  
  948.         /* Return the result. */
  949.  
  950.     return(Result);
  951. }
  952.